﻿namespace LinesOfAction.Model
{
    public class Move
    {
        protected bool Equals(Move other)
        {
            return Positions == other.Positions;
        }

        public override int GetHashCode()
        {
            return Positions.GetHashCode();
        }

        public static bool operator ==(Move left, Move right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(Move left, Move right)
        {
            return !Equals(left, right);
        }

        public static readonly Move invalidMove = new Move(new Point(ushort.MaxValue, ushort.MaxValue),
                                                           new Point(ushort.MaxValue, ushort.MaxValue));

        public override string ToString()
        {
            var text = string.Format("{0} --> {1}",Source,Target);

            if(this == invalidMove)
            {
                text = "Invalid Move";
            }

            return text;
        }

        private ushort Positions { get; set; }
        
        public Move(Move move)
        {
            Positions = move.Positions;
        }

        public Move(Point _point1, Point _point2)
        {
            Source = _point1;
            Target = _point2;
        }

        public override bool Equals(object obj)
        {
            return Positions == ((Move) obj).Positions;
        }

        public Point Target
        {
            get
            {
                ushort x = 7 << 9;
                ushort y = 7 << 6;
                
                x &= Positions;
                x >>=  9;
                y &= Positions;
                y >>=  6;

                return new Point(x, y);
            }
            set
            {
                var x = value.X;
                var y = value.Y;

                x <<= 9;
                Positions |= x;
                y <<= 6;
                Positions |= y;
            }
        }

        public Point Source
        {
            get
            {
                ushort x = 7 << 3;
                ushort y = 7;

                x &= Positions;
                x >>= 3;
                y &= Positions;

                return new Point(x, y);
            }
            set
            {
                var x = value.X;
                var y = value.Y;

                x <<= 3;

                Positions |= x;
                Positions |= y;
            }
        }
    }
}
